<template>
  <div id="manageUserView">
    <a-form :model="searchParams" layout="inline" style="flex-wrap: nowrap">
      <!-- 搜索条件项 -->
      <a-form-item
        field="id"
        label="用户ID"
        style="min-width: 160px; margin-right: 12px"
      >
        <a-input-number
          v-model="searchParams.id"
          placeholder="用户ID"
          style="width: 120px"
        />
      </a-form-item>

      <a-form-item
        field="username"
        label="用户名"
        style="min-width: 180px; margin-right: 12px"
      >
        <a-input
          v-model="searchParams.username"
          placeholder="用户名"
          style="width: 140px"
        />
      </a-form-item>

      <a-form-item
        field="clazz"
        label="班级"
        style="min-width: 160px; margin-right: 12px"
      >
        <a-input
          v-model="searchParams.clazz"
          placeholder="班级"
          style="width: 120px"
        />
      </a-form-item>

      <a-form-item
        field="userRole"
        label="角色"
        style="min-width: 140px; margin-right: 12px"
      >
        <a-select
          v-model="searchParams.userRole"
          placeholder="角色"
          style="width: 100px"
          allow-clear
        >
          <a-option value="user">user</a-option>
          <a-option value="admin">admin</a-option>
        </a-select>
      </a-form-item>

      <!-- 按钮组 -->
      <a-form-item style="flex-shrink: 0; margin-left: auto">
        <a-space :size="10" :wrap="false">
          <a-button type="primary" @click="doSubmit" style="min-width: 100px">
            查找
          </a-button>
          <a-button
            type="primary"
            @click="router.push({ path: '/add/user' })"
            style="min-width: 100px"
          >
            创建用户
          </a-button>
          <a-button
            type="primary"
            @click="getSymbolFile"
            style="min-width: 120px"
          >
            获取批量新增模板
          </a-button>
          <a-button
            type="primary"
            @click="visible = true"
            style="min-width: 120px"
          >
            批量新增
          </a-button>
          <a-button type="primary" status="danger" @click="doCleanCommonUser">
            删除普通用户
          </a-button>
          <a-button
            type="primary"
            status="danger"
            :disabled="selectedIds.length === 0"
            @click="doBatchDelete"
          >
            批量删除（{{ selectedIds.length }}）
          </a-button>
          <a-checkbox v-model="allSelected" @change="handleSelectAll">
            全选
          </a-checkbox>
        </a-space>
      </a-form-item>
      <!-- 新增清理确认对话框 -->
      <a-modal
        v-model:visible="cleanModalVisible"
        title="确认清理"
        @ok="cleanAllCommonUser"
        @cancel="cleanModalVisible = false"
      >
        <p>确定要清理所有普通用户吗？此操作不可恢复！</p>
        <template #footer>
          <a-button @click="cleanModalVisible = false">取消</a-button>
          <a-button type="primary" status="danger" @click="cleanAllCommonUser">
            确定清理
          </a-button>
        </template>
      </a-modal>
    </a-form>
    <a-modal
      v-model:visible="visible"
      title="批量上传用户"
      @ok="handleUpload"
      @cancel="handleCancel"
      :ok-button-props="{ loading }"
    >
      <a-upload
        v-model:file-list="fileList"
        accept=".txt"
        :show-file-list="false"
        @change="handleFileChange"
      >
        <template #upload-button>
          <div
            :class="['upload-area', { 'has-file': fileList.length }]"
            :style="{ borderColor: fileList.length ? '#3498db' : '' }"
          >
            <icon-file v-if="fileList.length" style="margin-right: 8px" />
            <span>
              {{ fileList[0]?.name || "点击选择文件" }}
            </span>
            <a-button
              v-if="!fileList.length"
              type="outline"
              style="margin-top: 12px"
            >
              <icon-upload />
              选择文件
            </a-button>
            <a-button
              v-else
              type="text"
              status="danger"
              @click.stop="handleRemove"
              style="margin-left: 8px"
            >
              <icon-delete />
            </a-button>
          </div>
        </template>
      </a-upload>
    </a-modal>
    <a-table
      :ref="tableRef"
      :columns="columns"
      :data="dataList"
      :pagination="pagination"
      @page-change="onPageChange"
      @sorter-change="handleSorterChange"
    >
      <template #acceptedQuestionIds="{ record }">
        <a-space wrap>
          <template
            v-for="(acceptedQuestionId, index) of JSON.parse(
              record.acceptedQuestionIds
            )"
            :key="index"
          >
            <a-tag
              v-if="acceptedQuestionId !== 0"
              color="arcoblue"
              class="question-tag"
            >
              {{ acceptedQuestionId }}
            </a-tag>
          </template>
        </a-space>
      </template>
      <template #optional="{ record }">
        <a-space>
          <a-button type="primary" @click="doUpdate(record)">修改</a-button>
          <a-button status="danger" @click="doDelete(record)">删除</a-button>
        </a-space>
      </template>
      <template #selector="{ record }">
        <a-checkbox
          v-model="selectedIds"
          :value="record.id"
          @change="handleSelect()"
        />
      </template>
    </a-table>
  </div>
</template>

<script setup lang="ts">
import { onMounted, reactive, ref, watchEffect } from "vue";
import {
  OpenAPI,
  User,
  UserControllerService,
  UserQueryRequest,
} from "../../../api";
import message from "@arco-design/web-vue/es/message";
import { useRouter } from "vue-router";
import { FileItem, TableColumnData } from "@arco-design/web-vue";

const tableRef = ref();
// 多选id
const selectedIds = ref<number[]>([]);
const allSelected = ref(false);
const cleanModalVisible = ref(false);
const dataList = ref<Array<User>>([]);
const total = ref<number>(0);
const searchParams = ref<UserQueryRequest>({
  id: undefined,
  username: undefined,
  clazz: undefined,
  userRole: undefined,
  pageSize: 10,
  current: 1,
  sortField: undefined,
  sortOrder: undefined,
});
const pagination = reactive({
  ...searchParams.value,
  showTotal: true,
  total: total,
  showJumper: true,
});
const onPageChange = (current: number) => {
  selectedIds.value = [];
  allSelected.value = false;
  pagination.current = current;
  searchParams.value.current = current;
  loadData();
};
// 新增清理方法
const doCleanCommonUser = async () => {
  cleanModalVisible.value = true;
};
const loadData = async () => {
  const res = await UserControllerService.pageQueryUser(searchParams.value);
  if (res.code === 0) {
    dataList.value = res.data?.records ?? [];
    total.value = res.data?.total ?? 0;
  } else {
    message.error("加载失败，" + res.message);
  }
};

/**
 * 监听 searchParams 变量，改变时触发页面的重新加载
 */
watchEffect(() => {
  loadData();
});

/**
 * 页面加载时，请求数据
 */
onMounted(() => {
  loadData();
});

const columns = ref<TableColumnData[]>([
  {
    title: "id",
    dataIndex: "id",
    width: 150,
    sortable: {
      sortDirections: ["ascend", "descend"],
      // 关键：禁用前端排序，触发服务端请求
      sorter: () => true as unknown as number,
    },
  },
  {
    title: "用户名",
    dataIndex: "username",
    ellipsis: true,
    tooltip: true,
    width: 100,
  },
  {
    title: "密码",
    dataIndex: "password",
    ellipsis: true,
    tooltip: true,
    width: 200,
  },
  {
    title: "分数",
    dataIndex: "score",
    width: 100,
    sortable: {
      sortDirections: ["ascend", "descend"],
      // 关键：禁用前端排序，触发服务端请求
      sorter: () => true as unknown as number,
    },
  },
  {
    title: "班级",
    dataIndex: "clazz",
    width: 100,
  },
  {
    title: "通过题目id",
    dataIndex: "acceptedQuestionIds",
    slotName: "acceptedQuestionIds",
    width: 200,
  },
  {
    title: "用户角色",
    dataIndex: "userRole",
    width: 100,
  },
  {
    title: "创建时间",
    dataIndex: "createTime",
    width: 170,
    sortable: {
      sortDirections: ["ascend", "descend"],
      sorter: () => true as unknown as number,
    },
  },
  {
    title: "修改时间",
    dataIndex: "updateTime",
    width: 170,
  },
  {
    title: "操作",
    slotName: "optional",
    width: 170,
  },
  {
    title: "选择",
    slotName: "selector",
    width: 70,
  },
]);
const cleanAllCommonUser = async () => {
  cleanModalVisible.value = false;
  message.loading("正在删除中~");
  const res = await UserControllerService.cleanCommonUser();
  if (res.code === 0) {
    message.success("删除成功");
    await loadData();
  } else {
    message.error(res.message ?? "删除失败");
  }
};
const doDelete = async (user: User) => {
  message.loading("正在删除中~");
  const res = await UserControllerService.deleteUser({
    id: Number(user.id),
  });
  if (res.code === 0) {
    message.success("删除成功");
    await loadData();
  } else {
    message.error(res.message ?? "删除失败");
  }
};

const router = useRouter();

const doUpdate = (user: User) => {
  router.push({
    path: "/update/user",
    query: {
      id: user.id,
    },
  });
};

// 批量上传相关状态
const visible = ref(false);
const singleFile = ref<File | null>(null); // 改为单文件引用
const loading = ref(false);

// 处理文件上传

// 存储文件对象
// 状态管理
const fileList = ref<FileItem[]>([]); // 使用 FileItem[] 类型

// 文件变化回调
const handleFileChange = (files: FileItem[], fileItem: FileItem) => {
  fileList.value = files;
  selectedFile.value = fileItem.file; // 文件暂存到内存
};

// 移除文件
const handleRemove = () => {
  fileList.value = [];
};
const selectedFile = ref<File | undefined>(undefined);

const handleUpload = async () => {
  if (!selectedFile.value) {
    message.error("请先选择上传文件");
    return;
  }

  try {
    loading.value = true;
    const formData = new FormData();
    formData.append("file", selectedFile.value);
    const res = await UserControllerService.addUserByFile({
      file: formData.get("file") as Blob,
    });
    if (res.code === 0) {
      message.success(`成功导入${res.data}条用户数据`);
      visible.value = false;
      singleFile.value = null;
      await loadData();
    } else {
      message.error(res.message || "上传失败");
    }
  } catch (e) {
    message.error("上传请求失败");
  } finally {
    loading.value = false;
    fileList.value = [];
  }
};

// 取消上传
const handleCancel = () => {
  singleFile.value = null;
};

// 处理排序逻辑
const handleSorterChange = (
  dataIndex: string,
  direction: string // 明确声明字面量类型
) => {
  searchParams.value.sortField = dataIndex as "id" | "createTime" | "score";
  searchParams.value.sortOrder =
    direction === "ascend"
      ? "ascend"
      : direction === "descend"
      ? "descend"
      : undefined;

  loadData(); // 触发后端请求
};

// 处理单个选择
const handleSelect = () => {
  allSelected.value = selectedIds.value.length === dataList.value.length;
};

const handleSelectAll = (value: boolean | (number | string | boolean)[]) => {
  // 类型断言确保是布尔值
  const checked = value as boolean;
  selectedIds.value = checked
    ? dataList.value.map((item) => item.id as number)
    : [];
};

// 新增批量删除方法
const doBatchDelete = async () => {
  if (selectedIds.value.length === 0) return;
  message.loading("正在删除中~");
  const res = await UserControllerService.batchDeleteUser({
    ids: selectedIds.value,
  });
  if (res.code === 0) {
    message.success(`成功删除 ${selectedIds.value.length} 条记录`);
    selectedIds.value = [];
    await loadData();
  } else {
    message.error(res.message ?? "批量删除失败");
  }
};

/**
 * 确认搜索，重新加载数据
 */
const doSubmit = () => {
  selectedIds.value = [];
  allSelected.value = false;
  // 这里需要重置搜索页号
  searchParams.value = {
    ...searchParams.value,
    current: 1,
  };
};

// 修改getSymbolFile方法
const getSymbolFile = () => {
  window.open(OpenAPI.BASE + "/file/download", "_blank");
};
</script>

<style scoped>
.upload-area {
  border: 1px dashed var(--color-border-3);
  border-radius: 4px;
  padding: 20px;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.3s;

  &:hover {
    border-color: var(--color-primary-light-3);
  }
}
</style>
